#include "directory_operation.h"

static int cdll(userOpInfo_t *info,char *toPrintPath){
    char sql[4096]={0};
    sprintf(sql,"select * from file_info where id=%d;",info->ID);
    int sqlret=mysql_query(info->mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","1cd.. mysql_query",mysql_error(info->mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info->mysql);
    MYSQL_ROW row=mysql_fetch_row(res);
	mysql_free_result(res);
    if(atoi(row[3])==-1){//parentId为-1,已到达根目录,不可再往前
        printf("cd .. 错误!\n");
        return -1;
    }
    else{
        info->ID=atoi(row[3]);
		char sql1[4096]={0};
		sprintf(sql1,"select * from file_info where id=%d;",atoi(row[3]));
		sqlret=mysql_query(info->mysql,sql1);
		if(sqlret!=0){
			fprintf(stderr,"%s:%s\n","2cd.. mysql_query",mysql_error(info->mysql));
			exit(-1);
		}
		MYSQL_RES *res1=mysql_store_result(info->mysql);
		MYSQL_ROW row1=mysql_fetch_row(res1);
		memset(toPrintPath,0,strlen(toPrintPath));
        strcpy(toPrintPath,row1[6]);
        mysql_free_result(res1);
    }
    return 1;
}

static int cdrr(userOpInfo_t *info,char *toPrintPath){
    char sql[4096]={0};
    snprintf(sql,sizeof(sql),"select * from file_info where (filename ='%s' and username ='%s' and parent_id= %d );",info->opName,info->userName,info->ID);//
    int sqlret=mysql_query(info->mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","cdDir mysql_query",mysql_error(info->mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info->mysql);
    int resNum=mysql_num_rows(res);
    if(resNum==0){
        printf("cd操作错误: 没有指定路径!\n");
        return -1;
    }else{
        MYSQL_ROW row=mysql_fetch_row(res);
        if(row[5][0]=='d'){
            info->ID=atoi(row[0]);
            strcpy(toPrintPath,row[6]);
        }

    }
    mysql_free_result(res);
    return 1;
} 

int cdDir(userOpInfo_t *info,  char *toPrintPath){
    //提前存一下当前路径,如果cd失败,还是待在原路径
    int oldPath=info->ID;

    //拆分strtok
    char destDir[1024]={0};
    strcpy(destDir,info->opName);
    char *p=destDir;
    p=strtok(destDir,"/");
    //printf("p=%s\n",p);
    if(p == NULL) {
        printf("p is NULL\n");
        return -1;
    }
    while(p!=NULL){
        strcpy(info->opName,p);
        if(strcmp(p,"..")==0){
            if(cdll(info,toPrintPath)==-1){//访问根目录之上
                info->ID=oldPath;
                return -1;
            }
        }
        else if(strcmp(p,".")==0){
            pwdDir(*info,toPrintPath);
        }

        else{
            if(cdrr(info,toPrintPath)==-1){//当前位置无该目录
                info->ID=oldPath;
                return -1;
            }
        }
        p=strtok(NULL,"/");
    }

    return 1;
}


//传出一个完整的pwd
int pwdDir(userOpInfo_t info,char *toPrintPath){
    //打印父结点的path
    char sql[4096]={0};
    sprintf(sql,"select * from file_info where id=%d ;",info.ID);
    int sqlret=mysql_query(info.mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","pwdDir mysql_query",mysql_error(info.mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info.mysql);//得到查询的表
    MYSQL_ROW row=mysql_fetch_row(res);
    strcpy(toPrintPath,row[6]);

    mysql_free_result(res);
    return 1;
}

//传出一个整的字符串  如果是文件夹 加个/
int lsDir(userOpInfo_t info, char *toPrintLs) {
    char sql[4096] = {0};
    sprintf(sql, "select * from file_info where parent_id = %d;", info.ID);
    
    int sqlret = mysql_query(info.mysql, sql);
    if(sqlret != 0) {
        fprintf(stderr, "%s:%s\n", "lsDir mysql_query", mysql_error(info.mysql));
        exit(-1);
    }

    MYSQL_RES *res = mysql_store_result(info.mysql);
    int resNum = mysql_num_rows(res);
    if(resNum == 0) {
        mysql_free_result(res);
        return 1;
    }

    char *p = toPrintLs;
    int remaining_space = 4096; // 假设缓冲区足够大，最好使用实际大小
    
    for(int i = 0; i < resNum; i++) {
        MYSQL_ROW row = mysql_fetch_row(res);
        if(!row[1]) continue; // 确保文件名存在
        
        int written = 0;
        if(row[5] && row[5][0] == 'd') { // 是目录
            written = snprintf(p, remaining_space, "%s/  ", row[1]);
        } else { // 是文件
            written = snprintf(p, remaining_space, "%s  ", row[1]);
        }
        
        if(written < 0 || written >= remaining_space) {
            // 缓冲区不足处理
            break;
        }
        
        p += written;
        remaining_space -= written;
    }

    mysql_free_result(res);
    return 1;
}


int mkDir(userOpInfo_t info){
    //插入时要把path弄好
    //判断是否已有该目录
    char sql[4096]={0};
    snprintf(sql,sizeof(sql),"select * from file_info where (filename ='%s' and username ='%s' and parent_id= %d );",info.opName,info.userName,info.ID);//
    int sqlret=mysql_query(info.mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","mkDir1 mysql_query",mysql_error(info.mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info.mysql);
    int resNum=mysql_num_rows(res);
    mysql_free_result(res);//释放上一次
    if(resNum==0){//没有该目录,可以创建    
                  //把要插入的path先拼接好
        char sql1[4096]={0};
        char path[2048]={0};
        sprintf(sql1,"select * from file_info where id=%d;",info.ID);//取出当前path
        sqlret=mysql_query(info.mysql,sql1);
        if(sqlret!=0){
            fprintf(stderr,"%s:%s\n","mkDir2 mysql_query",mysql_error(info.mysql));
            exit(-1);
        }
        MYSQL_RES *res1=mysql_store_result(info.mysql);
        MYSQL_ROW row=mysql_fetch_row(res1);
        snprintf(path,sizeof(path),"%s%s/",row[6],info.opName);
        //插入数据库
        char sql2[8192]={0};
        snprintf(sql2,sizeof(sql2),"insert into file_info (filename,username,parent_id,type,path) values ('%s','%s',%d,'%s','%s');",info.opName,info.userName,info.ID,"d",path);
        sqlret=mysql_query(info.mysql,sql2);
        if(sqlret!=0){
            fprintf(stderr,"%s:%s\n","mkDir3 mysql_query",mysql_error(info.mysql));
            exit(-1);
        }
        mysql_free_result(res1);
    }else{//已经有这个名字的目录了
        printf("mkdir操作错误: 已经有此目录了!\n");
        return -1;
    }
    return 1;
}

int rmDir(userOpInfo_t info){
    char sql[4096]={0};
    snprintf(sql,sizeof(sql),"select * from file_info where filename ='%s' and username='%s' and parent_id= %d;",info.opName,info.userName,info.ID);
    int sqlret=mysql_query(info.mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","rmDir1 mysql_query",mysql_error(info.mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info.mysql);
    int resNum=mysql_num_rows(res);
    if(resNum==0){
        printf("rm操作错误: 没有指定文件夹!\n");
        return -1;
    }
    else{
        MYSQL_ROW row=mysql_fetch_row(res);
        if(row[5][0]=='d'){
            char sql1[4096]={0};
            sprintf(sql1,"delete from file_info where id=%s;",row[0]);
            sqlret=mysql_query(info.mysql,sql1);
            if(sqlret!=0){
                fprintf(stderr,"%s:%s\n","rmDir2 mysql_query",mysql_error(info.mysql));
                exit(-1);
            }
        }
        else{
            printf("rmFile错误: 无法用rmdir删除一个文件!\n");
            return -1;
        }
    }
    mysql_free_result(res);
    return 1;
}

int rmFile(userOpInfo_t info){
    char sql[4096]={0};
    snprintf(sql,sizeof(sql),"select * from file_info where filename ='%s' and username='%s' and parent_id= %d;",info.opName,info.userName,info.ID);
    int sqlret=mysql_query(info.mysql,sql);
    if(sqlret!=0){
        fprintf(stderr,"%s:%s\n","rmDir1 mysql_query",mysql_error(info.mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info.mysql);
    int resNum=mysql_num_rows(res);
    if(resNum==0){
        printf("rm操作错误: 没有指定文件!\n");
        return -1;
    }
    else{
        MYSQL_ROW row=mysql_fetch_row(res);
        if(row[5][0]=='f'){
           //不管quotenum是不是等于1这一行都要删除
            char sql1[4096]={0};
            sprintf(sql1,"delete from file_info where id=%s;",row[0]);
            sqlret=mysql_query(info.mysql,sql1);
            if(sqlret!=0){
                fprintf(stderr,"%s:%s\n","rmDir2 mysql_query",mysql_error(info.mysql));
                exit(-1);
            }
            if(atoi(row[7])==1){//quote等于1顺便删文件
                char filePath[4096]={0};
                snprintf(filePath,sizeof(filePath),"%s/%s",info.addr,row[4]);//row[4]是哈希值
                remove(filePath);
            }
        } 
        else{
            printf("rmFile错误: 无法用rm删除一个目录!\n");
            return -1;
        }
        if(row[5][0]=='f'&&atoi(row[7])!=1){
            //把所有人有这个文件的全部-1
            char sql1[4096]={0};
            sprintf(sql1,"update file_info set quotenum=quotenum-1 where hash='%s' and type='f';",row[4]);//hash相同的人全-1
            sqlret=mysql_query(info.mysql,sql1);
            if(sqlret!=0){
                fprintf(stderr,"%s:%s\n","rmDir2 mysql_query",mysql_error(info.mysql));
                exit(-1);
            }            
        }
    }
    mysql_free_result(res);
    return 1;
}

int deleteAccount(userOpInfo_t *userOpInfo){
    //用户表删除用户修改墓碑值为-1
    userOpInfo_t *useropinfo = userOpInfo;
    char query[4096];
    MYSQL_RES *res;
    MYSQL_ROW row;
    snprintf(query,sizeof(query),
             "UPDATE user_info SET is_deleted = 1 WHERE username = '%s';",useropinfo->userName);
    if(mysql_query(useropinfo->mysql,query)){
        fprintf(stderr,"%s\n",mysql_error(useropinfo->mysql));
        return -1;
    }
    //文件表删除用户

        //1删除具体文件
    memset(query,0,sizeof(query));
    snprintf(query,sizeof(query),
             "select hash from file_info where username='%s' and type='f' and quotenum=1 ;",useropinfo->userName);
    if(mysql_query(useropinfo->mysql,query)){
        fprintf(stderr,"%s\n",mysql_error(useropinfo->mysql));
        return -1;
    }
    res=mysql_store_result(useropinfo->mysql);
    for(int i=0;i<(int)mysql_num_rows(res);i++){
        row=mysql_fetch_row(res);
        char filePath[4096]={0};
        snprintf(filePath,sizeof(filePath),"%s/%s",useropinfo->addr,row[0]);
        remove(filePath);  
    }
    mysql_free_result(res);

    //2删目标所有文件表内容
    memset(query,0,sizeof(query));
    snprintf(query,sizeof(query),
             "SELECT * FROM file_info WHERE username='%s';",useropinfo->userName);//找该用户所有文件
    if(mysql_query(useropinfo->mysql,query)){
        fprintf(stderr,"%s\n",mysql_error(useropinfo->mysql));
        return -1;
    }   
    res = mysql_store_result(useropinfo->mysql);
    for(int i=0;i<(int)mysql_num_rows(res);i++){
        row=mysql_fetch_row(res);
        //如果是quote不等于1的文件,把其他所有hash值等于此文件的行-1
        if(row[5][0]=='f'&&atoi(row[7])!=1){
            char sql1[4096]={0};
            sprintf(sql1,"update file_info set quotenum=quotenum-1 where hash='%s' and type='f';",row[4]);//本来写的文件名一样的减1,但应该是hash值一样的减1
            int sqlret=mysql_query(useropinfo->mysql,sql1);
            if(sqlret!=0){
                fprintf(stderr,"%s:%s\n"," mysql_query",mysql_error(useropinfo->mysql));
                exit(-1);
            }         
        }
        //每行都需要删除
        char sql1[4096]={0};
        sprintf(sql1,"delete from file_info where id=%s;",row[0]);
        int sqlret=mysql_query(useropinfo->mysql,sql1);
        if(sqlret!=0){
            fprintf(stderr,"%s:%s\n","mysql_query",mysql_error(useropinfo->mysql));
            exit(-1);
        }
    
    }

    mysql_free_result(res);
    
    return 1;
}


int treeDir(userOpInfo_t info,char *indent,char *toPrint) {
    char sql[4096]={0};
    snprintf(sql,sizeof(sql),"select id,filename,type from file_info where parent_id=%d",info.ID);
        if (mysql_query(info.mysql, sql) != 0) {
        fprintf(stderr, "tree: %s\n", mysql_error(info.mysql));
        exit(-1);
    }
    MYSQL_RES *res=mysql_store_result(info.mysql);
    int resNum=mysql_num_rows(res);
    MYSQL_ROW row;
    
    for(int i=0;i<resNum;i++){
        row=mysql_fetch_row(res);
        info.ID=atoi(row[0]);//递归加深度
        //printf("test\n");     
        //打印当前行  缩进 + └── + 名字 + 拖尾
        //先确定拖尾 
        char tail[10]={0};
        if(row[2][0]=='d'){
            strcpy(tail,"/");
        }
        else{
            memset(tail,0,sizeof(tail));
        }
        //拼接当前行 并打印
        char connector[4096]={0};
        snprintf(connector,sizeof(connector),"%s└──%s%s\n",indent,row[1],tail);//设置缩进
        //printf("%s\n",connector);
        //snprintf(toPrint,sizeof(toPrint),"%s\n%s",toPrint,connector);
        //如果当前行是目录,进入递归
        strcat(toPrint,connector);
    

        if(row[2][0]=='d'){
            char newIndent[256]="   ";
            snprintf(newIndent,sizeof(newIndent),"%s%s",indent,"   ");
            treeDir(info,newIndent,toPrint);
        }


    }
    mysql_free_result(res);
    return 1;
}

